package demo1;
//写一个泛型类，其中有一个方法求数组中的最大值
//泛型的上界
class Alg<T extends Comparable<T>>{//指定了T是有边界的，如果没有边界就是Object类
    //泛型方法
    public T findMax(T[] array){
        T max = array[0];
        for (int i = 0; i < array.length; i++) {
            //这里报错的原因是：引用类型不可以通过大于和小于进行比较，所以需要设置泛型上界，对传入的类型进行约束。引用类型要进行比较，
            // 需要让引用类型发实现Comparable接口，然后调用CompareTo方法进行比较
            //尽管在编译的时候会将泛型类编译为Object类，但是Object类也没有实现Comparable接口，所以还是不能进行比较，必须让泛型类实现Comparable接口
            if (max.compareTo(array[i])<0){
                max = array[i];
            }
        }
        return max;
    }
}
//比如这里有一个引用类型Person
class Person{

}//但是在main方法里面却不能传入Person该类型参数，因为该类型没有实现Comparable<>接口

//泛型静态方法，使得在不进行泛型类的实例化就可以调用方法
class ALg2{
//    public T findMax(T[] array){这种写法会报错，因为这里类没有说明T是什么，在定义成员方法时通过class Alg<T>并进行实例化得到T的类型
    public static<T extends Comparable<T>> T findMax(T[] array){
        T max = array[0];
        for (int i = 0; i < array.length; i++) {
            if (max.compareTo(array[i])<0){//.compareTo会报错，因为类型T不知道有没有实现Comparable接口，所以要定义一个泛型上界
                max = array[i];
            }
        }
        return max;
    }
}


public class Test2 {
    public static void main(String[] args) {
        //不进行类的实例化直接实现静态方法
        Integer[] array = {1,56,13,92,6};
        Integer max = ALg2.findMax(array);//通过类名调用静态方法，没有进行类的实例化
        //或者
//        Integer max = ALg2.<Integer>findMax(array);这样写也可以代替是上面一行代码，也可以不写<Integer>表示传入的类型参数是Integer，因为Java会自行进行推导
        System.out.println(max);
    }
    public static void main1(String[] args) {
        Alg<Integer> alg = new Alg<>();
        Integer[] array = {1,54,2,23,7};
        Integer max = alg.findMax(array);//可以写成Integer max = alg.<Integer>findMax(array);的形式，表示findMax传入的是一个Integer类型的数据
        //如果想不实例化对象就调用findMax方法--->静态方法
        System.out.println(max);
        Alg<String> alg1 = new Alg<>();//String实现了comparable接口，所以可以进行实例化
//        Alg<Person> alg2 = new Alg<Person>();//这样就会报错，因为Person肯定是自己定义的，属于引用类型，不在泛型所约束的类型范围内
    }
}
